# -*- coding: UTF-8 -*- #
"""
-------真正的勇士， 敢于直面惨淡的Warning、 敢于正视淋漓的Error-----
@author : 贾鹏博
@file : 13、高级定位 xpath 和 uiautomator定位 .py
@time : 2022/5/27 15:55
"""

"""
xpath 定位进阶
    1、层级定位 ：
        父节点定位子节点
        子节点定位父节点
        子节点定位兄弟节点
        爷爷节点定位孙子节点
nodename  选取此节点的所有节点
/    从根节点选取
//   从匹配选择的当前节点选择文档中的节点，而不考虑它们的位置
.    选取当前节点
..   选取当前的父节点
@    选取属性
*    匹配任何元素的节点      /bookstore/*  选取 bookstore 元素的所有子元素  。  //*   选取文档中的所有元素
@*   匹配任何属性节点        //title[@*]  选取所有带有属性的 title 元素  
node()   匹配任何类型的节点
bookstore   选取 bookstore 元素的所有子节点
/bookstore   选取根元素 bookstore
bookstore/book  选取属于 bookstore 的子元素的所有 book 元素
//book      选取所有 book 子元素，而不管它们在文档中的位置
//bookstore//book   选取属于 bookstore 元素后代的所有 book 元素，而不管它们位于 bookstore 之下的什么位置
//@lang   选取名为 lang 的所有属性

/bookstore/book[1]   选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()]   选取属于 bookstore 子元素的最后一个元素
/bookstore/book[last()-1]  选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素
//title[@lang]  选取所有拥有名为 lang 的属性的 title 元素
//title[@lang='eng']  选取所有 title 元素，且这些元素拥有值为 eng 的 lang 属性
/bookstore/book[price>35.00]   选取 bookstore 元素的所有 book 元素，且其中的 price 元素的值须大于 35.00
/bookstore/book[price>35.00]/title   选取 bookstore 元素中的 book 元素的所有 title 元素，且其中的 price 元素的值须大于 35.00



uiautomator 定位表达式
    优点：
        uiautomator 是 android 的工作引擎，速度快
        xpath 定位速度慢
    缺点：
        表达式书写复杂，容易写错 IDE 没有提示
    通过resourceid定位  new UiSelector().resourceId('id')
    通过classname定位   new UiSelector().className('className')
    通过content-desc定位   new UiSelector().description('contenet-des属性')
    通过文本定位    
        new UiSelector().text('text文本')
        如果文本较长，可以用 textContains模糊匹配  new UiSelector().textContains('包含text文本')
        同样可以用textStartsWith以某一个文本开头来匹配  new UiSelector().textStartWith('以文本开头')
        也可以用正则表达式 textMatches 匹配   new UiSelector().textMatches('正则表达式')
    组合定位 ：
        例一 ： id 与 text 属性组合
        id_text = 'resourceId("com.baidu.yuedu:id/webbooktitle").text("小说")'
        driver.find_element_by_android_uiautomator(id_text).click()
        例二 ： class 与 text 属性组合
        class_text = 'className("android.widget.TextView").text("图书")'
        driver.find_element_by_android_uiautomator(class_text).click()
    父子关系定位 childSelector
        有时候不能直接定位某个元素，但是它的父元素很好定位，可以通过父元素找子元素
        son = 'resourceId("com.baidu.yuedu:id/rl_tabs").childSelector(text("股票"))'
    兄弟定位 fromParent 
        有时候元素不好定位，但是跟他相邻的兄弟元素很好定位，这时候就可以通过兄弟元素，找到同一父级元素的子元素
        brother = 'resourceId("com.baidu.yuedu:id/lefttitle").fromParent(text("用户"))'
    
    实现滚动查找
        'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("查找的文本").instance(0));'
        
        
    
        
                
滑动定位
    
"""

import time
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy


class TestSearch:
    def setup(self):
        desired_caps = {}
        desired_caps['platformName'] = "Android"
        desired_caps['platformVersion'] = '6.0'
        desired_caps['deviceName'] = 'emulator-5554'
        desired_caps['appPackage'] = 'com.xueqiu.android'
        desired_caps['appActivity'] = '.view.WelcomeActivityAlias'
        desired_caps['noReset'] = 'true'
        # desired_caps['dontStopAppOnReset'] = 'true'
        desired_caps['skipDeviceInitialization'] = 'true'
        desired_caps['unicodeKeyBoard'] = 'true'
        desired_caps['resetKeyBoard'] = 'true'
        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
        # 隐式等待
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    # xpath 定位
    def test_get_current(self):
        self.driver.find_element(AppiumBy.ID, 'com.xueqiu.android:id/tv_search').click()
        self.driver.find_element(AppiumBy.ID, 'com.xueqiu.android:id/search_input_text').send_keys('阿里巴巴')
        self.driver.find_element(AppiumBy.XPATH,
                                 "//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴-SW']").click()
        current_price = float(self.driver.find_element(AppiumBy.XPATH,
                                                       "//*[@text='09988']/../../..//*[@resource-id='com.xueqiu.android:id/current_price']").text)
        print(f'当前 09988 对应的股票价格为 {current_price}')
        assert current_price == 61.75

    # uiautomator 定位
    def test_myinfo(self):
        """
        1、点击我的，进入到个人信息页面
        2、点击登录，进入到登录界面
        3、输入用户名，输入密码
        4、点击登录
        :return:
        """
        time.sleep(5)
        # 点击我的   文本
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR('new UiSelector().text("我的")')).click()
        # 点击账号登录   包含文本
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR('new UiSelector().textContains("帐号密码")')).click()
        # 输入用户名
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR(
            'new UiSelector().resourceId("com.xueqiu.android:id/login_account")')).send_keys('12345')
        # 输入密码
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR(
            'new UiSelector().resourceId("com.xueqiu.android:id/login_password")')).send_keys('12345')
        time.sleep(3)
        # 点击登录  以文本开头
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR(
            'new UiSelector().resourceId("com.xueqiu.android:id/button_next")')).click()

        # 组合查询
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR(
            'new UiSelector().resourceId("com.xueqiu.android:id/tab_name").text("我的").className("")'))

        # 父节点查找   股票
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR(
            'new UiSelector().resourceId("com.xueqiu.android:id/title_container").childSelector(text("股票"))'))

        # 滚动雪球首页

    def test_scroll_find_element(self):
        self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR('new UiScrollable(new UiSelector().'
                                                              'scrollable(true).instance(0)).'
                                                              'scrollIntoView(new UiSelector().text("贫民窟的大富翁").'
                                                              'instance(0));'))
